﻿using System.Security.Claims;
using ApiLib.AppStart;
using ApiLib.Models;
using ApiLib.Utils;
using Furion;
using Furion.FriendlyException;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;

namespace ApiLib.Common.Filters;

/// <summary>
/// 自定义授权筛选器
/// </summary>
public class DefaultAuthorizeFilter : IAsyncAuthorizationFilter
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var baseAuthorization = GlobalConfig.BaseAuthorization;
        //if (baseAuthorization==null || WebUtil.UseJwt)
        if (baseAuthorization==null)
        {
            await Task.CompletedTask;
            return;
        }
        // 获取控制器信息
        var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        // 获取控制器类型
        var controllerType = actionDescriptor!.ControllerTypeInfo;
        // 获取 Action 类型
        var methodType = actionDescriptor.MethodInfo;
        // 是否匿名访问
        var allowAnonymous = context.Filters.Any(u => u is IAllowAnonymousFilter)
                             || controllerType.IsDefined(typeof(AllowAnonymousAttribute), true)
                             || methodType.IsDefined(typeof(AllowAnonymousAttribute), true);
        
        var requestPath = context.HttpContext.Request.Path.Value;
        if (allowAnonymous || (requestPath != null && GlobalConfig.RouteWhiteList.Contains(requestPath)))
        {
            await Task.CompletedTask;
            return;
        }
        // 不是匿名才处理权限检查
        var token = baseAuthorization.GetToken(context.HttpContext.Request);

        // 在 MVC 项目中，如果检查失败，则跳转到登录页
        if (!string.IsNullOrEmpty(token))
        {
            var baseUser = baseAuthorization.Authorization(context.HttpContext.Request);
            if (baseUser != null)
            {
                App.User.AddIdentity(new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Sid, baseUser.GetSid() ?? ""),
                    new Claim(ClaimTypes.Name, baseUser.GetName() ?? ""),
                    new Claim(ClaimTypes.Authentication, token),
                }));
                await Task.CompletedTask;
                return;
            }
        }

        // 返回未授权
        context.Result = BadPageResult.Status401Unauthorized;// new UnauthorizedResult();
    }
}